import React, { PureComponent, Fragment } from 'react';
import { connect } from 'dva';
import moment from 'moment';

import {
  Form,
  Card,
  Button,
  Modal,
  Input,
  Table,
  Divider,
  Tag,
  TreeSelect,
  Select,
  Row,
  Col,
  Popconfirm,
} from 'antd';

import PageHeaderLayout from '../../layouts/PageHeaderLayout';

import styles from './User.less';

const FormItem = Form.Item;
const {Option} = Select;

const editDeptTreeData = values => {
  return values.map(dept => {
    if (dept.children && dept.children.length > 0) {
      return {
        value: String(dept.id),
        label: dept.name,
        key: String(dept.key),
        children: editDeptTreeData(dept.children),
      };
    } else {
      return {
        value: String(dept.id),
        label: dept.name,
        key: String(dept.key),
      };
    }
  });
};

@connect(({ users, loading }) => ({
  users,
  loading: loading.models.users,
}))
@Form.create()
export default class User extends PureComponent {
  state = {
    modalVisible: false,
    modalWidth: (window.innerWidth / 3),
    modalAction: null,
    formValues: {},
  };

  componentDidMount() {
    window.addEventListener('resize', this.resize);
    const { dispatch } = this.props;
    dispatch({
      type: 'users/fetch',
    });
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.resize);
  }

  onDeptChange = (value) => {
    const { dispatch } = this.props;
    dispatch({
      type: 'users/fetchRolesByDept',
      payload: {
        deptId: value,
      },
    });
  };

  onHandleOk = (handleOk) => {
    const { form } = this.props;
    form.validateFields((err, fieldsValue) => {
      if (err) return;
      form.resetFields();
      handleOk(fieldsValue);
    });
  };

  resize = () => {
    this.setState({
      modalWidth: (window.innerWidth / 3),
    });
  };

  handleAddModalVisible = flag => {

    const t = this;
    const { dispatch, form } = t.props;
    form.resetFields();
    dispatch({
      type: 'users/fetchDeptList',
    }).then(
      t.setState({
        modalVisible: !!flag,
        modalAction: 'add',
        formValues: {},
      })
    );
  };

  handleUpdModalVisible = (flag, user) => {

    const t = this;
    const { dispatch, form } = t.props;
    if (flag) {

      dispatch({
        type: 'users/fetchDeptList',
      })
        .then(
          () => {
            dispatch({
              type: 'users/fetchRolesByDept',
              payload: {
                deptId: user.deptId,
              },
            });
          }
        )
        .then(
          () => {
            t.setState({
              modalVisible: true,
              modalAction: 'update',
              formValues: user,
            });

            form.setFieldsValue({
              username: user.username,
              phone: user.phone,
              deptId: [user.deptId.toString()],
              role: user.roleList.map(role => role.roleId.toString()),
              delFlag: user.delFlag,
            });
          }
        );

    } else {
      form.resetFields();
      t.setState({
        modalVisible: false,
        modalAction: null,
        formValues: {},
      });
    }
  };

  handleAdd = user => {
    const { dispatch } = this.props;
    dispatch({
      type: 'users/add',
      payload: {
        ...user,
      },
    });

    this.setState({
      modalVisible: false,
    });
  };

  delUser = user => {
    const { dispatch } = this.props;
    dispatch({
      type: 'users/del',
      payload: {
        userId: user.userId,
      },
    });

    this.setState({
      modalVisible: false,
    });
  };

  handleUpd = user => {
    const { dispatch } = this.props;
    const { formValues } = this.state;
    dispatch({
      type: 'users/upd',
      payload: {
        userId: formValues.userId,
        username: user.username,
        phone: user.phone,
        delFlag: user.delFlag,
        role: user.role,
        deptId: Number(user.deptId[0]),
      },
    });

    this.setState({
      modalVisible: false,
    });
  };

  renderAddUserForm = () => {
    const {
      form,
      users: { deptList, roleList },
    } = this.props;

    const roleSelectChildren = [];
    roleList.forEach(item => {
      roleSelectChildren.push(
        <Option key={item.roleId}>{item.roleDesc}</Option>
      );
    });

    return (
      <Form layout="vertical">
        <Row>
          <Col>
            <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 19 }} label="用户名">
              {form.getFieldDecorator('username', {
                rules: [{ min: 2, max: 20, required: true, message: '必填' }],
              })(<Input placeholder="请输入" />)}
            </FormItem>
          </Col>
        </Row>
        <Row>
          <Col>
            <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 19 }} label="密码">
              {form.getFieldDecorator('password', {
                rules: [{ min: 6, max: 20, required: true, message: '必填' }],
              })(<Input placeholder="请输入" />)}
            </FormItem>
          </Col>
        </Row>
        <Row>
          <Col>
            <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 19 }} label="手机">
              {form.getFieldDecorator('phone', {
                rules: [{ min: 11, max: 11, required: true, message: '必填' }],
              })(<Input placeholder="请输入" />)}
            </FormItem>
          </Col>
        </Row>
        <Row>
          <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 19 }} label="所属部门">
            {form.getFieldDecorator('deptId', {
              rules: [{ required: true, message: '必填' }],
            })(
              <TreeSelect
                allowClear
                dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                treeData={editDeptTreeData(deptList)}
                placeholder="请选择"
                treeDefaultExpandAll
                onChange={this.onDeptChange}
              />
            )}
          </FormItem>
        </Row>
        <Row>
          <Col>
            <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 19 }} label="角色">
              {form.getFieldDecorator('role', {
                rules: [{ required: true, message: '必填' }],
              })(
                <Select
                  mode="multiple"
                  placeholder="请选择"
                >
                  {roleSelectChildren}
                </Select>
              )}
            </FormItem>
          </Col>
        </Row>
      </Form>
    );
  };

  renderUpdUserForm = () => {
    const {
      form,
      users: { deptList, roleList },
    } = this.props;

    const roleSelectChildren = [];
    roleList.forEach(item => {
      roleSelectChildren.push(
        <Option key={item.roleId}>{item.roleName}</Option>
      );
    });

    return (
      <Form layout="vertical">
        <Row>
          <Col>
            <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 19 }} label="用户名">
              {form.getFieldDecorator('username', {
                rules: [{ min: 2, max: 20, required: true, message: '必填' }],
              })(<Input placeholder="请输入" />)}
            </FormItem>
          </Col>
        </Row>
        <Row>
          <Col>
            <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 19 }} label="手机">
              {form.getFieldDecorator('phone', {
                rules: [{ min: 11, max: 11, required: true, message: '必填' }],
              })(<Input placeholder="请输入" />)}
            </FormItem>
          </Col>
        </Row>
        <Row>
          <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 19 }} label="所属部门">
            {form.getFieldDecorator('deptId', {
              rules: [{ required: true, message: '必填' }],
            })(
              <TreeSelect
                allowClear
                dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                treeData={editDeptTreeData(deptList)}
                placeholder="请选择"
                treeDefaultExpandAll
                onChange={this.onDeptChange}
              />
            )}
          </FormItem>
        </Row>
        <Row>
          <Col>
            <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 19 }} label="角色">
              {form.getFieldDecorator('role', {
                rules: [{ required: true, message: '必填' }],
              })(
                <Select
                  mode="multiple"
                  placeholder="请选择"
                >
                  {roleSelectChildren}
                </Select>
              )}
            </FormItem>
          </Col>
        </Row>
        <Row>
          <Col>
            <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 19 }} label="状态">
              {form.getFieldDecorator('delFlag', {
                rules: [{ required: true, message: '必填' }],
              })(
                <Select placeholder="请选择">
                  <Option value="0">有效</Option>
                  <Option value="1">无效</Option>
                </Select>
              )}
            </FormItem>
          </Col>
        </Row>
      </Form>
    );
  };

  renderModalForm = (type) => {
    if (type === 'add') {
      return this.renderAddUserForm();
    } else if (type === 'update') {
      return this.renderUpdUserForm();
    } else {
      return null;
    }
  };

  render() {
    const { modalVisible, modalWidth, modalAction, formValues } = this.state;
    const {
      users: { users },
      loading,
    } = this.props;

    const columns = [
      {
        title: '序号',
        dataIndex: 'userId',
      },
      {
        title: '用户名',
        dataIndex: 'username',
      },
      {
        title: '手机号',
        dataIndex: 'phone',
      },
      {
        title: '角色',
        dataIndex: 'roleList',
        render: data => {
          const roles = data.map(role => role.roleDesc);
          return roles.toString();
        },
      },
      {
        title: '创建时间',
        dataIndex: 'createTime',
        render: createTime => moment(createTime).format('YYYY-MM-DD HH:mm'),
      },
      {
        title: '状态',
        dataIndex: 'delFlag',
        render: delFlag => (delFlag ? <Tag color="#f50">有效</Tag> : <Tag color="#f50">无效</Tag>),
      },
      {
        title: '所在部门',
        dataIndex: 'deptName',
      },
      {
        title: '操作',
        render: (_, user) => (
          <Fragment>
            <a onClick={() => this.handleUpdModalVisible(true, user)}>编辑</a>
            <Divider type="vertical" />
            <Popconfirm title="确定删除?" onConfirm={() => this.delUser(user)} okText="删除" cancelText="取消">
              <a>删除</a>
            </Popconfirm>
          </Fragment>
        ),
      },
    ];

    let parentMethods = {};
    if (modalAction === 'add') {
      parentMethods = {
        handleOk: this.handleAdd,
        handleModalVisible: this.handleAddModalVisible,
        modalTitle: '新建用户',
      };
    } else if (modalAction === 'update') {
      parentMethods = {
        handleOk: this.handleUpd,
        handleModalVisible: this.handleUpdModalVisible,
        modalTitle: '修改用户',
        formValues,
      };
    }

    return (
      <PageHeaderLayout title="用户管理">
        <Card bordered={false}>
          <div className={styles.tableList}>
            <div className={styles.tableListOperator}>
              <Button icon="plus" type="primary" onClick={() => this.handleAddModalVisible(true)}>
                新建
              </Button>
            </div>
            <Table
              loading={loading}
              rowKey="userId"
              dataSource={users.list}
              columns={columns}
              pagination={users.pagination}
            />
          </div>
        </Card>
        <Modal
          title={parentMethods.modalTitle}
          width={modalWidth}
          visible={modalVisible}
          onOk={() => this.onHandleOk(parentMethods.handleOk)}
          onCancel={() => parentMethods.handleModalVisible()}
        >
          {this.renderModalForm(modalAction)}
        </Modal>
      </PageHeaderLayout>
    );
  }
}
